import { useEffect, useRef, useState } from "react";
import { IDataItem, IHeader, IOffset } from "./types";
import { useUpdateEffect } from "./use";

export const useVirtualScorll = () => app => {
  let list: IDataItem[] = app.ctx.dataSource;

  const [offset, setOffset]: [IOffset, any] = useState({ x: 0, y: 0 });

  const [result, setResult] = useState({ viewData: [], header: [] });

  const containerRef = useRef(null);

  app.ctx.containerRef = containerRef

  const getViewData = () => {
    let viewInfo = app.ctx.viewInfo;

    let { itemWidth, itemHeight, header } = viewInfo;

    // let x = Math.round(offset.x / itemWidth);
    // let y = Math.round(offset.y / itemHeight);

    let x = ~~(offset.x / itemWidth);
    let y = ~~(offset.y / itemHeight);

    // if (viewInfo.transposition) [x, y] = [y, x];

    let viewData: IDataItem[][] = [];
    let viewHeader: IHeader[] = [];

    for (let vY = 0; vY < viewInfo.viewY; vY++) {
      let xItem: IDataItem[] = [];
      let vX = 0;

      for (vX = 0; vX < viewInfo.fixed; vX++) {
        xItem[vX] = list[y + vY][vX];
      }

      for (; vX < viewInfo.viewX; vX++) {
        xItem[vX] = list[y + vY][x + vX];
      }
      viewData[vY] = xItem;
    }

    if (header) {
      let viewLength = viewInfo.transposition ? viewInfo.viewY : viewInfo.viewX;
      let i = 0;

      for (; i < viewInfo.fixed; i++) {
        viewHeader[i] = header[i];
      }

      for (; i < viewLength; i++) {
        viewHeader[i] = header[x + i];
      }

      app.ctx.viewHeader = viewHeader;
    }

    setResult({ viewData, header: viewHeader });
  };

  app.actions.getViewData = getViewData;

  useEffect(() => {
    app.actions.clearScroll = () => containerRef.current?.scrollTo(0, 0);
  }, [setOffset]);

  useEffect(() => {
    console.log(
      "%c 🍷 app.ctx?.viewInfo?.itemHight: ",
      "font-size:20px;background-color: #2EAFB0;color:#fff;",
      app.ctx?.viewInfo?.itemHight,
      app.ctx?.viewInfo?.header
    );
    app.ctx.wrapperPropsStyle = {
      width: add(app.ctx?.viewInfo?.header, "width") || 500,
      height: (app.ctx?.viewInfo?.itemHight || 50) * app.ctx?.viewInfo?.y
    };
  }, [app.ctx?.viewInfo?.header, app.ctx?.viewInfo?.itemHight]);

  useUpdateEffect(() => {
    getViewData();
  }, [offset, list, setResult]);

  return {
    props: ctx => {
      let { itemWidth, itemHeight, viewX, viewY } = app.ctx.viewInfo || {};
      console.log(
        "%c 🥘 app.ctx: ",
        "font-size:20px;background-color: #E41A6A;color:#fff;",
        app.ctx
      );

      return {
        data: {
          ...result,
          viewInfo: { itemHeight }
        },
        tableProps: {
          position: "absolute",
          // ...app.ctx.tableProps
          top: offset.y,
          left: offset.x,
          width: itemWidth * viewX + 30
        },
        containerProps: {
          ref: (ele: any) => {
            containerRef.current = ele;
          },
          onScroll: (e: any) => {
            let offset = { x: e.target.scrollLeft, y: e.target.scrollTop };
            if (app.ctx.viewInfo.transposition)
              [offset.x, offset.y] = [offset.y, offset.x];
            setOffset(offset);
          },
          style: {
            // overflow: "scroll" as const,
            // 'z-index': -1,
            position: "relative",
            overflow: "auto",
            height: itemHeight * (viewY + 1) ,
            width: itemWidth * viewX
          }
        },
        wrapperProps: {
          style: app.ctx.wrapperPropsStyle || {}
        }
      };
    }
  };
};

const add = (arr: any[], key: string) => {
  return arr?.reduce?.((acc: number, cur: any) => acc + cur[key], 0);
};
